use std::sync::Arc;

use async_trait::async_trait;
use datafusion::datasource::TableProvider;
use datafusion::prelude::DataFrame;

use common::{Entry, LResult};

pub type EngineRef = Box<dyn Engine>;
pub type EngineFactoryRef = Box<dyn EngineFactory>;

#[async_trait]
pub trait Engine: Send + Sync {
    fn name(&self) -> &String;
    async fn write(&mut self, entry: Entry) -> LResult<()>;

    fn table_provider(&self) -> LResult<Arc<dyn TableProvider>>;

    async fn delete(&mut self) -> LResult<()>;
}

pub trait EngineFactory: Send + Sync {

    fn name(&self) -> &'static str;
    fn create(&self, measurement: String) -> EngineRef;
    fn post_transform_query(&self, df: DataFrame) -> LResult<DataFrame>;
}

pub type TableScanOptionRef = Arc<TableScanOption>;

#[derive(Default, Debug)]
pub struct TableScanOption {
    pub projection: Option<Vec<usize>>,
    pub limit: Option<usize>,
}
